/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：VirtualModel.js<br>
 * 日期：2016年11月8日<br>
 * 作者: 王中山<br>
 * 功能：<br>
 * 
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

window.makeNamespace(window,"Rainier.UI.V2");

/**
 * 类型名称：Rainier.UI.V2.VirtualModel<br>
 * 类型功能：通用器件模型<br>
 */
Rainier.UI.V2.VirtualModel = Rainier.UI.V2.DynamicModel.extend({
	
	NAME : "Rainier.UI.V2.VirtualModel",
	
	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.init<br>
	 * 函数功能：构造函数<br>
	 * 参数输入:property属性对象<br>
	 * 异常信息：无<br>
	 */
	init : function(property){
		var dummy = jQuery.extend(true,{},property);
		this._super(dummy?property:{});
		this.cviCommandLine = null;	//虚拟仪器启动参数信息
		this.cviInfo = null;	//虚拟仪器网表对象(目前只有函数信号发生器存在)
		this.cviResult = '';
	},
	
	/**	
	 * 函数名称：Rainier.UI.V2.VirtualModel.tranlateToSpice<br>
	 * 函数功能：将元件翻译成spice语句<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：sSpice:string<br>
	 * 异常信息：无<br>
	 */
	tranlateToSpice : function(){
		if (this.getProperty().modelProperty.cviInfo) {
			if (!this.cviInfo) {
				this.cviInfo = this.getProperty().modelProperty.cviInfo;
			}
		}
		if(this.cviInfo){
			this.cviInfo.lastTime 	= 0;
			this.cviInfo.lastSum 	= 0;
			this.cviInfo.beginTime = 0;
			//TODO:格式化为spice codemodel
			var modelPro = this.getProperty().modelProperty;
			if(modelPro){
				var spiceModel = modelPro.additional.spiceModel.sm;
				if(spiceModel){
					spiceModel.replace(/\\t/g,' ');
					var spice 	= this.replaceSpiceModel(spiceModel,modelPro);
					spice 		= this.replaceProperty(spice);
					return spice;
				}
			}
		}
		else{
			return this._super();
		}
	},
	
	/**	
	 * 函数名称：Rainier.UI.V2.VirtualModel.tranlateToSpice<br>
	 * 函数功能：将元件翻译成spice语句<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：sSpice:string<br>
	 * 异常信息：无<br>
	 */
	tranlateToDynamicText : function(data,spice){
		var ret = '';
		//开关调节后需调整电流电压计算算法
		//beginTime 解决电路运行期间开关动态调节产生的数据不准确问题
		//重新启动电路解算需对缓存数据清零
		if(this.cviInfo.lastTime == undefined || (data.time != undefined&& data.time == 0)){
			data.lastTime 	= this.cviInfo.lastTime = data.time;
			data.lastSum 	= this.cviInfo.lastSum = 0;			
			data.resultNum 	= this.cviInfo.resultNum = 1;
			this.cviInfo.beginTime = this.cviInfo.lastTime;
			return;
		}
		//万用表类型处理
		if(this.cviInfo['MultimeterMode']){
			data.mode 		= this.cviInfo['MultimeterMode'];
		}
		data.lastTime 	= (this.cviInfo.lastTime == undefined)?0:this.cviInfo.lastTime;
		data.lastSum	= (this.cviInfo.lastSum  == undefined)?0:this.cviInfo.lastSum;
		data.resultNum	= (this.cviInfo.resultNum  == undefined)?1:this.cviInfo.resultNum;
		data.beginTime 	= this.cviInfo.beginTime;
		//内部算法基本一致
		//有效值=sqrt（（∑（当前电压值*当前电压值*（当前时间-上次取值时间）））/(总时间-beginTime)），电流算法一致
		ret 	= eval(spice);
		this.cviInfo.lastTime 	= data.time;
		this.cviInfo.lastSum  	= data.lastSum;
		this.cviInfo.resultNum  = data.resultNum;
		if(ret === Infinity){
			return '0.000';
		}
		else if(this.cviInfo['RANGE']){
			if(ret > this.cviInfo['RANGE']){
				return '0.000';
			}
			else if (this.cviInfo['RANGE'] < 1) {
				ret = ret*1000;
			}
		}
		return ret.toFixed(3);
	},



	
	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.getTstep<br>
	 * 函数功能：获取步长<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：tstep : 初始时间步长<br>
	 * 异常信息：无<br>
	 */
	getTstep : function(){
		var tstep 	= this._super();
		if(this.cviInfo&&this.cviInfo['FREQ']){
			tstep 	= 1/(this.cviInfo['FREQ']*2);
		}
		return tstep;
	},
	
	/**	
	 * 函数名称：Rainier.UI.V2.VirtualModel.orderPorts<br>
	 * 函数功能：对虚拟仪器端口遍历，如果单个端口存在连线，相应的端口无连线，默认接地，即赋为0<br>
	 * 参数输入：editorId : 把当前的虚拟仪器信息绑定到对应的Editor上<br>
	 * 参数输入：ds : is default start<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	orderPorts : function(editorId,ds){
		var inputs   = this.getInputPorts();
		var outputs  = this.getOutputPorts();
		var hybrids  = this.getHybridPorts();
		var ports = [];
		var _this = this;
		ports = ports.concat(inputs.data).concat(outputs.data).concat(hybrids.data);
		var path = this.getProperty().modelProperty.path;
		var label = this.getProperty().modelProperty.label;
		var cviParams = {};
		var portProArr = ['a','b','c','d','e','f','g','h'];
		
		$.each(ports,function(i,p){
			var node = p.getProperty().modelProperty.node;
			var nodeId = p.getProperty().modelProperty.id;
			var portName = p.getProperty().modelProperty.name;
			if (p.incomings.getSize() <= 0 && p.outgoings.getSize() <= 0 ) {
				node = -1;
			}
			cviParams[portName] = node;
		});
		
		for(var i = 0;i < portProArr.length;++i){
			var portPro = portProArr[i];
			var p = portPro + 'p';
			var n = portPro + 'n';
			if(cviParams[p] && cviParams[n]){
				if(cviParams[p] !== -1 || cviParams[n] !== -1){
					// if(cviParams[p] === -1){
					// 	cviParams[p] = 0;
					// }
					// else 
					if(cviParams[n] === -1){
						cviParams[n] = 0;
					}
				}				
			}
		}
		
		var cvitype  = VIRTUAL_INSTRUMENT_PREFIX + path;
		var uuid	 = editorId.slice(0,6);
		var instance = label;// +'_'+uuid;
		var msg      = 'open(';
		msg			+= '--cvi-type=' + cvitype;
		msg			+= ' --cvi-instance-id=' + instance.toLowerCase();
		msg			+= ' --client-id=-1';
		for(var key in cviParams){
			msg     += ' --' + key + '=v' + cviParams[key];
		}
		if(ds){
			msg			+= ' --default-start=1';
		}
		msg 		+= ')';
		
		this.cviCommandLine = {type:USER_CVI_INTER_MSG,cvitype:cvitype,instanceId:instance.toLowerCase(),msg:msg};
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.startCvi<br>
	 * 函数功能：启动虚拟仪器<br>
	 * 参数输入：ds : is default start<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	startCvi : function(ds){
		//启动虚拟仪器；对启动的虚拟仪器绑定到对应的editor面板上
		var context      = app.getContext();
		var activeEditor = context.getActiveEditor();
		var webSocket    = context.getWebSocket(); 
		var currentEditorId= activeEditor.getUuid();
		this.orderPorts(currentEditorId,ds);
			
		if(webSocket){
			webSocket.sendMsgByInfo(this.cviCommandLine);
		}                                                  
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.closeCvi<br>
	 * 函数功能：关闭虚拟仪器<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	closeCvi : function(){
		this.sendCviMsg('close');
		this.cviCommandLine = null;
		this.cviResult = '';
	},

	/**
	 * [sendStartToCvi description]
	 * @return {[type]} [description]
	 */
	sendStartToCvi : function(msg){
		this.sendCviMsg(msg);
	},

	/**
	 * [sendCviMsg description]
	 * @param  {[type]} msg [description]
	 * @return {[type]}     [description]
	 */
	sendCviMsg : function(msg){
		//启动虚拟仪器；对启动的虚拟仪器绑定到对应的editor面板上
		if(this.cviCommandLine){
			var virtualInfo = this.cviCommandLine;
			var msgInfo	    = {type:USER_CVI_INTER_MSG,cvitype:virtualInfo.cvitype,instanceId:virtualInfo.instanceId.toLowerCase(),msg:msg};
			var ctx = null;
			if(window.AppContext){
				ctx = window.AppContext;
			}
			if(ctx){
				var webSocket = ctx.getWebSocket();
				if(webSocket){
					webSocket.sendMsgByInfo(msgInfo);
				}                                                  
			}
		}
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.handleCommand<br>
	 * 函数功能：处理虚拟仪器发送来的命令<br>
	 * 参数输入：json：json字符串<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	handleCommand : function(json){
		var content = JSON.parse(json);			
		if (content) {
			if (content.command_type) {
				var args = content.content;
				this.cviInfo = args;
				switch(content.command_type){
					case 'spice':
					this.updateSpiceCmd(args);
					break;
					case 'dynamic':
					this.updateDynamicCmd(args);
					break;
					default:
					break;
				}
			}
		}
	},

	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.updateSpiceCmd<br>
	 * 函数功能：根据参数修改网表<br>
	 * 参数输入：content:命令参数内容<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	updateSpiceCmd : function (content) {
		//测试用例
		//var content = JSON.parse('{	"command_type":"spice",	"content":{		"WaveType":	"WAVE_SQUAR",		"FREQ":	1000,		"AMPL":	0.010000,		"OFST":	0,		"DUTY":	"-1",		"POINTNUMBER":	"-1",		"POINTVALUE":	[-1]	}}');
		//content = content.content;
		var exprimentState = this.getCurrentRunState();
		if(exprimentState){
			//正在运行
			var app 	   = window.AppContext.application;
			var editorView = app.findViewById("Rainier.UI.V2.ApplicationEditorView");  
			//第一步：关闭当前实验
			editorView.exprimentPause();
			//第二步：重新启动实验
			editorView.exprimentRun();
			
		}
	},

	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.updateDynamicCmd<br>
	 * 函数功能：根据参数修改动态元件显示<br>
	 * 参数输入：content:命令参数内容<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	updateDynamicCmd : function (content) {
		//TODO	重组content产生result 按照虚拟仪器定义condition
		if(content){
			//万用表关闭操作特殊处理
			if(content.POWER != undefined && content.POWER == 0){
				this.cviInfo = null;
			}
			else{				
				this.cviResult = decodeURI(content.instrumentValue);
			}
		}	
	},

	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.replaceProperty<br>
	 * 函数功能：替换动态属性内容<br>
	 * 参数输入：spice:命令参数内容<br>
	 * 参数输出：无<br>
	 * 函数返回：无<br>
	 * 异常信息：无<br>
	 */
	replaceProperty : function(spice){
		var index = spice.indexOf('#');
		while(index >= 0){
			var spaceIndex 	= spice.indexOf('#',index+1);
			var replaceStr 	= spice.substr(index,spaceIndex-index+1);
			var reg 		= new RegExp("("+replaceStr+")","g");   

			var contentKey 	= spice.substr(index+1,spaceIndex-index-1);
			var value		= this.cviInfo[contentKey];
			//函数信号发生器特殊情况处理 /(ㄒoㄒ)/~~
			if (contentKey === 'WaveType') {
				var arrObj 	= {'WAVE_SINE':0,'WAVE_SQUAR':1,'WAVE_TRIANGULAR':2,'WAVE_NOISE':3,'WAVE_ARB':4,};
				value = (arrObj[value] !== undefined)?arrObj[value]:'';
			}
			else if (contentKey === 'POINTVALUE') {
				value ='['+value.join(' ')+']';
				if(value === '[-1]'){
					value 	= '[0 0]';
				}
			}
			spice = spice.replace(reg,value);

			var lastIndex = index;
			index = spice.indexOf('#');
			if(lastIndex == index){
				break;
			}
		}
		return spice;
	},
	
	/**
	 * 函数名称：Rainier.UI.V2.VirtualModel.getCurrentRunState<br>
	 * 函数功能：获取当前的运行状态<br>
	 * 参数输入：无<br>
	 * 参数输出：无<br>
	 * 函数返回：当前的运行状态<br>
	 * 异常信息：无<br>
	 */
	getCurrentRunState : function(){
		var selectionStuff 	 = window.AppContext.selectionStuff;
		var runEditor		 = selectionStuff.activeRunEditor;
		//运行状态的activeRunEditor 存在，说明当前实验正在运行；不存在，说明实验未运行；
		if(runEditor){
			return true;
		}
		return false;
	},
});
